﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenNETCF.MTConnect;
using OpenNETCF.IoC;
using MachineSimulator.Interfaces;

namespace SimulatorAdapter
{
    public class Door : HostedSensor
    {
        private bool m_doorOpen;

        public Door()
            : base("door_open")
        {
        }

        [EventDataItem(
            ItemType = DataItemType.DOOR_STATE
            )]
        public bool DoorOpen
        {
            get { return m_doorOpen; }
            set
            {
                // only publish value changes
                if (value == m_doorOpen) return;

                // store the new value
                m_doorOpen = value;

                // calling this will notify the underlying Agent engine to publish this value out the MTConnect protocol interface
                RaisePropertyChanged("DoorOpen");
            }
        }
    }

    public abstract class HostedSensor : HostedComponentBase
    {
        public HostedSensor(string id)
        {
            this.ID = id;
        }

        public override ComponentType ComponentType
        {
            get { return OpenNETCF.MTConnect.ComponentType.Sensor; }
        }
    }

    public class MachineDevice : HostedDeviceBase
    {
        private string m_available;

        private HostedAxes m_axes;

        private MachineAdapter Adapter { get; set; }
        internal X XAxis { get; set; }
        internal Y YAxis { get; set; }
        internal Z ZAxis { get; set; }
        internal Systems Systems { get; set; }
        internal Controller Controller { get; set; }
        internal Door Door { get; set; }

        public MachineDevice(MachineAdapter adapter)
            : base(adapter)
        {
            Adapter = adapter;

            m_axes = new HostedAxes();
            XAxis = new X();
            YAxis = new Y();
            ZAxis = new Z();
            m_axes.Components.Add(XAxis);
            m_axes.Components.Add(YAxis);
            m_axes.Components.Add(ZAxis);

            Controller = new Controller();

            Systems = new Systems();

            Door = new Door();

            Available = "AVAILABLE";

            // put into the DI container so the UI can get at it easily
            RootWorkItem.Services.Add<IMachineInterface>(new MachineInterface(this));
            RootWorkItem.Services.AddNew<SimulationService, ISimulationService>();
        }

        public override string Manufacturer
        {
            get { return "OpenNETCF"; }
        }
        
        public override IEnumerable<IHostedComponent> Components
        {
            get 
            {
                return new IHostedComponent[]
                {
                    m_axes,
                    Controller,
                    Systems,
                    Door
                };
            }
        }
        
        [EventDataItem(
            ItemType=DataItemType.AVAILABILITY
            )]
        public string Available
        {
            get { return m_available; }
            set
            {
                // only publish value changes
                if (value == m_available) return;

                // store the new value
                m_available = value;

                // calling this will notify the underlying Agent engine to publish this value out the MTConnect protocol interface
                RaisePropertyChanged("Available");
            }
        }
    }
}
